package ooo.reindeer.commons;

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.databind.ObjectMapper;

import java.io.IOException;

public class StorageData implements Cloneable {

    static ObjectMapper mapper = new ObjectMapper();

//    @JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, property = "@C")
    Object data;

    @JsonCreator
    public StorageData(@JsonProperty("data") Object data) {
        this.data = data;
    }

    public static StorageData build(String str) {
        try {
            return mapper.readValue(str, StorageData.class);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }

    }

    public static StorageData build(byte[] bytes) {
        try {
            return mapper.readValue(bytes, StorageData.class);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }

    }

    public static <T> T buildData(String str) {
        return build(str).getData();

    }

    public static <T> T buildData(byte[] bytes) {
        return build(bytes).getData();

    }

    public static byte[] toBytes(Object object) {
        try {
            return mapper.writeValueAsBytes(new StorageData(object));
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    public static String toString(Object object) {
        try {
            return mapper.writeValueAsString(new StorageData(object));
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public StorageData clone() {
        try {
            return mapper.readValue(this.toString(), StorageData.class);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    public <T> T getData() {
        return (T) data;
    }

    public byte[] toBytes() {
        try {
            return mapper.writeValueAsBytes(this);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public String toString() {
        try {
            return mapper.writeValueAsString(this);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

}